using System;
using System.Web.Mvc;
using System.Web.Security;
using System.IO;
using System.Web;
using CommonLogging;
using TestWeb.Models;
using TestWeb.Repositories;
using TestWeb.Helpers;

namespace TestWeb.Controllers
{	
	/// <summary>
	/// The base class contains methods for concretes
	/// </summary>
	public class BaseController : Controller
	{
		#region Repositories
		
		/// <summary>
		/// The instance of LoaiTinTucRepository for accessing table LoaiTinTuc in database
		/// </summary>
		public LoaiTinTucRepository RepLoaiTinTuc = new LoaiTinTucRepository();
		
		/// <summary>
		/// The instance of NguoiDungRepository for accessing table NguoiDung in database
		/// </summary>
		public NguoiDungRepository RepNguoiDung = new NguoiDungRepository();
		
		/// <summary>
		/// The instance of TinTucRepository for accessing table TinTuc in database
		/// </summary>
		public TinTucRepository RepTinTuc = new TinTucRepository();
		
		#endregion
		
		#region Constants And Fields
		
		/// <summary>
		/// The logger instance
		/// </summary>
		public readonly ILogger Logger = LoggerManager.GetLogger(typeof(BaseController).Name);

		/// <summary>
		/// The default image
		/// </summary>
		public readonly string DefaultImage = "noimages.jpg";

		/// <summary>
		/// The default image upload directory
		/// </summary>
        public readonly string UploadImageDirectory = "/Content/UploadImages/";

		#endregion
		
		#region Utils

        /// <summary>
        /// RenderPartialView without model
        /// </summary>
        /// <param name="viewName"></param>
        /// <returns></returns>
        protected string RenderPartialViewToString(string viewName)
        {
            return RenderPartialViewToString(viewName, null);
        }

		/// <summary>
		/// Render a partial view and convert its content to string
		/// </summary>
		/// <param name="viewName">The name of partial view</param>
        /// <param name="model">Data Model</param>
        protected string RenderPartialViewToString(string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString("action");
            ViewData.Model = model;
            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);
                return sw.GetStringBuilder().ToString();
            }
        }

		/// <summary>
		/// The method for handling upload a file to server
		/// </summary>
		/// <param name="file">The file will be uploaded to server</param>
		/// <param name="dirPath">The directory which the file will be stored in</param>
		/// <param name="fileName">fileName will be created based on DateTime.Now as binary string and uploaded file extension</param>
		/// <param name="errTxt"></param>
		public bool UploadFile(HttpPostedFileBase file, string dirPath, ref string fileName)
		{
			try
			{
				FileInfo fileInfo = new FileInfo(file.FileName);
				fileName = DateTime.Now.ToBinary() + fileInfo.Extension;
				var fullPath = Path.Combine(Server.MapPath(dirPath), fileName);
			
				byte[] buffer = new byte[file.ContentLength];
				file.InputStream.Read(buffer, 0, file.ContentLength);
				
				using(FileStream newFile = new FileStream(fullPath, FileMode.Create, FileAccess.Write))
				{
					newFile.Write(buffer, 0, file.ContentLength);
				}
				return true;
			}
			catch (Exception ex)
			{
				if(ex.InnerException == null)
					Logger.ErrorFormat("UploadFile: {0}", ex.Message);
				else
					Logger.ErrorFormat("UploadFile: {0}", ex.InnerException.Message);
			}
			return false;
		}

		/// <summary>
		/// The method for deleting a file in server
		/// </summary>
		/// <param name="filePath">The file will be deleted in server</param>
		public void DeleteFile(string filePath)
		{
			try
			{
				FileInfo file = new FileInfo(Server.MapPath(filePath));
				if (file.Exists)
					file.Delete();
			}
			catch (Exception ex)
			{
				if(ex.InnerException == null)
					Logger.ErrorFormat("DeleteFile: {0}", ex.Message);
				else
					Logger.ErrorFormat("DeleteFile: {0}", ex.InnerException.Message);
			}
		}

		/// <summary>
		/// The method for sending email 
		/// </summary>
		/// <param name="subject">The subject of email</param>
		/// <param name="content">The content of email</param>
		/// <param name="to">The destination address will be received email</param>
		/// <param name="from">The source address</param>
		/// <param name="password">The password of source address</param>
		public bool SendMail(string subject, string content, string to, string from, string password)
		{
			try
			{
				System.Net.Mail.SmtpClient mailclient = new System.Net.Mail.SmtpClient();
                mailclient.Host = WebConfiguration.Instance.MailServer;
				mailclient.EnableSsl = true;
				mailclient.UseDefaultCredentials = true;
				mailclient.Credentials = new System.Net.NetworkCredential(from, password);
				
				System.Net.Mail.MailMessage mm = new System.Net.Mail.MailMessage(from, to);
				mm.Subject = subject;
				mm.IsBodyHtml = true;
				mm.Body = content;
				mailclient.Send(mm);
				
				return true;
			}
			catch (Exception ex)
			{
				if(ex.InnerException == null)
					Logger.ErrorFormat("SendMail: {0}", ex.Message);
				else
					Logger.ErrorFormat("SendMail: {0}", ex.InnerException.Message);
			}
			return false;
		}

		/// <summary>
		/// Select models which are used for some of views 
		/// </summary>
		/// <param name="viewModel">Object to be updated</param>
		public void UpdateModel(ViewModel viewModel)
		{
			var controllerName = (string)ControllerContext.RouteData.Values["Controller"];
			if (string.Compare(controllerName, "admin", StringComparison.OrdinalIgnoreCase) == 0)
			{
                viewModel.AllOfLoaiTinTucs = this.RepLoaiTinTuc.SelectAll();
			}
			else if (string.Compare(controllerName, "home", StringComparison.OrdinalIgnoreCase) == 0)
			{
			}
		}

		#endregion
		
	}
}
